home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / mondata.c < prev    next >
C/C++ Source or Header  |  1993-01-22  |  10KB  |  411 lines

  1. /*    SCCS Id: @(#)mondata.c    3.1    92/11/24    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "eshk.h"
  7. #include "epri.h"
  8.  
  9. /*    These routines provide basic data for any type of monster. */
  10.  
  11. #ifdef OVL0
  12.  
  13. boolean
  14. attacktype(ptr, atyp)
  15.     register struct    permonst    *ptr;
  16.     register int atyp;
  17. {
  18.     int    i;
  19.  
  20.     for(i = 0; i < NATTK; i++)
  21.         if(ptr->mattk[i].aatyp == atyp) return(TRUE);
  22.  
  23.     return(FALSE);
  24. }
  25.  
  26. #endif /* OVL0 */
  27. #ifdef OVLB
  28.  
  29. boolean
  30. poly_when_stoned(ptr)
  31.     struct permonst *ptr;
  32. {
  33.     return (is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] &&
  34.         !(mons[PM_STONE_GOLEM].geno & G_GENOD));    /* allow G_EXTINCT */
  35. }
  36.  
  37. boolean
  38. resists_drli(ptr)    /* returns TRUE if monster is drain-life resistant */
  39.  
  40.     register struct permonst *ptr;
  41. {
  42.     return(is_undead(ptr) || is_demon(ptr) || is_were(ptr));
  43. }
  44.  
  45. #endif /* OVLB */
  46. #ifdef OVL0
  47.  
  48. boolean
  49. ranged_attk(ptr)    /* returns TRUE if monster can attack at range */
  50.     register struct permonst *ptr;
  51. {
  52.     register int    i, j;
  53.     register int atk_mask = (1<<AT_BREA) | (1<<AT_SPIT) | (1<<AT_GAZE);
  54.  
  55.     /* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP) ||
  56.         attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE) ||
  57.         attacktype(ptr, AT_MAGC));
  58.        but that's too slow -dlc
  59.      */
  60.     for(i = 0; i < NATTK; i++) {
  61.         if((j=ptr->mattk[i].aatyp) >= AT_WEAP || (atk_mask & (1<<j)))
  62.         return TRUE;
  63.     }
  64.  
  65.     return(FALSE);
  66. }
  67.  
  68. boolean
  69. hates_silver(ptr)
  70. register struct permonst *ptr;
  71. /* returns TRUE if monster is especially affected by silver weapons */
  72. {
  73.     return (is_were(ptr) || ptr->mlet==S_VAMPIRE || is_demon(ptr) ||
  74.         ptr == &mons[PM_SHADE] ||
  75.         (ptr->mlet==S_IMP && ptr != &mons[PM_TENGU]));
  76. }
  77.  
  78. #endif /* OVL0 */
  79. #ifdef OVL1
  80.  
  81. boolean
  82. can_track(ptr)        /* returns TRUE if monster can track well */
  83.     register struct permonst *ptr;
  84. {
  85.     if (uwep && uwep->oartifact == ART_EXCALIBUR)
  86.         return TRUE;
  87.     else
  88.         return(haseyes(ptr));
  89. }
  90.  
  91. #endif /* OVL1 */
  92. #ifdef OVLB
  93.  
  94. #if defined(POLYSELF) || defined(MUSE)
  95. boolean
  96. sliparm(ptr)    /* creature will slide out of armor */
  97.     register struct permonst *ptr;
  98. {
  99.     return is_whirly(ptr) || ptr->msize <= MZ_SMALL ||
  100.         ptr == &mons[PM_GHOST];
  101. }
  102.  
  103. boolean
  104. breakarm(ptr)    /* creature will break out of armor */
  105.     register struct permonst *ptr;
  106. {
  107.     return((bigmonst(ptr) || (ptr->msize > MZ_SMALL && !humanoid(ptr))
  108.                     || ptr == &mons[PM_MARILITH]) && !sliparm(ptr));
  109.     /* Marilith is about the only case of a monster which is otherwise
  110.      * humanoid but cannot wear armor (too many arms).  Centaurs would
  111.      * be another except that they are already accounted for by
  112.      * bigmonst.
  113.      */
  114. }
  115. #endif
  116. #endif /* OVLB */
  117. #ifdef OVL1
  118.  
  119. boolean
  120. sticks(ptr)    /* creature sticks other creatures it hits */
  121.     register struct permonst *ptr;
  122. {
  123.     return(dmgtype(ptr,AD_STCK) || dmgtype(ptr,AD_WRAP) ||
  124.         attacktype(ptr,AT_HUGS));
  125. }
  126.  
  127. boolean
  128. dmgtype(ptr, dtyp)
  129.     register struct    permonst    *ptr;
  130.     register int dtyp;
  131. {
  132.     int    i;
  133.  
  134.     for(i = 0; i < NATTK; i++)
  135.         if(ptr->mattk[i].adtyp == dtyp) return TRUE;
  136.  
  137.     return FALSE;
  138. }
  139.  
  140. /* returns the maximum damage a defender can do to the attacker via
  141.  * a passive defense */
  142. int
  143. max_passive_dmg(mdef, magr)
  144.     register struct monst *mdef, *magr;
  145. {
  146.     int    i, dmg = 0;
  147.     uchar adtyp;
  148.  
  149.     for(i = 0; i < NATTK; i++)
  150.     if(mdef->data->mattk[i].aatyp == AT_NONE) {
  151.         adtyp = mdef->data->mattk[i].adtyp;
  152.         if((adtyp == AD_ACID && !resists_acid(magr->data)) ||
  153.             (adtyp == AD_COLD && !resists_cold(magr->data)) ||
  154.             (adtyp == AD_FIRE && !resists_fire(magr->data)) ||
  155.             (adtyp == AD_ELEC && !resists_elec(magr->data))) {
  156.         dmg = mdef->data->mattk[i].damn;
  157.         if(!dmg) dmg = mdef->data->mlevel+1;
  158.         dmg *= mdef->data->mattk[i].damd;
  159.         } else dmg = 0;
  160.  
  161.         return dmg;
  162.     }
  163.     return 0;
  164. }
  165.  
  166. #endif /* OVL1 */
  167. #ifdef OVL0
  168.  
  169. int
  170. monsndx(ptr)        /* return an index into the mons array */
  171.     struct    permonst    *ptr;
  172. {
  173.     register int    i;
  174.  
  175.     if(ptr == &playermon) return(-1);
  176.  
  177.     i = (int)(ptr - &mons[0]);
  178.     if(i < 0 || i >= NUMMONS) {    
  179.         panic("monsndx - could not index monster (%lx)", (long)ptr);
  180.         return FALSE;        /* will not get here */
  181.     }
  182.  
  183.     return(i);
  184. }
  185.  
  186. #endif /* OVL0 */
  187. #ifdef OVL1
  188.  
  189.  
  190. int
  191. name_to_mon(str)
  192. char *str;
  193. {
  194.     /* Be careful.  We must check the entire string in case it was
  195.      * something such as "ettin zombie corpse".  The calling routine
  196.      * doesn't know about the "corpse" until the monster name has
  197.      * already been taken off the front, so we have to be able to
  198.      * read the name with extraneous stuff such as "corpse" stuck on
  199.      * the end.
  200.      * This causes a problem for names which prefix other names such
  201.      * as "ettin" on "ettin zombie".  In this case we want the _longest_
  202.      * name which exists.
  203.      * This also permits plurals created by adding suffixes such as 's'
  204.      * or 'es'.  Other plurals must still be handled explicitly.
  205.      */
  206.     register int i;
  207.     register int mntmp = -1;
  208.     register char *s;
  209.     char buf[BUFSZ];
  210.     int len, slen;
  211.  
  212.     Strcpy(buf, str);
  213.     str = buf;
  214.     if (!strncmp(str, "a ", 2)) str += 2;
  215.     else if (!strncmp(str, "an ", 3)) str += 3;
  216.  
  217.     /* Some irregular plurals */
  218.     if (!strncmpi(str, "incubi", 6)) return PM_INCUBUS;
  219.     if (!strncmpi(str, "succubi", 7)) return PM_SUCCUBUS;
  220.     if (!strncmpi(str, "violet fungi", 12)) return PM_VIOLET_FUNGUS;
  221.     if (!strncmpi(str, "homunculi", 9)) return PM_HOMUNCULUS;
  222.     if (!strncmpi(str, "baluchitheria", 13)) return PM_BALUCHITHERIUM;
  223.     if (!strncmpi(str, "lurkers above", 13)) return PM_LURKER_ABOVE;
  224.     if (!strncmpi(str, "cavemen", 7)) return PM_CAVEMAN;
  225.     if (!strncmpi(str, "cavewomen", 9)) return PM_CAVEWOMAN;
  226.     if (!strncmpi(str, "zruties", 7)) return PM_ZRUTY;
  227.     if (!strncmpi(str, "djinn", 5)) return PM_DJINNI;
  228.     if (!strncmpi(str, "mumakil", 7)) return PM_MUMAK;
  229.     if ((s = strstri(str, "vortices")) != 0)
  230.         Strcpy(s+4, "ex");
  231.     /* be careful with "ies"; "priest", "zombies" */
  232.     else if ((s = strstri(str, "jellies")) != 0 ||
  233.          (s = strstri(str, "mummies")) != 0)
  234.         Strcpy(s+4, "y");
  235.     /* luckily no monster names end in fe or ve with ves plurals */
  236.     else if ((s = strstri(str, "ves")) != 0)
  237.         Strcpy(s, "f");
  238.  
  239.     slen = strlen(str);
  240.     for (len = 0, i = 0; i < NUMMONS; i++) {
  241.         register int m_i_len = strlen(mons[i].mname);
  242.         if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
  243.         if (m_i_len == slen) return i;    /* exact match */
  244.         else if (slen > m_i_len &&
  245.             (str[m_i_len] == ' ' ||
  246.              !strcmpi(&str[m_i_len], "s") ||
  247.              !strncmpi(&str[m_i_len], "s ", 2) ||
  248.              !strcmpi(&str[m_i_len], "es") ||
  249.              !strncmpi(&str[m_i_len], "es ", 3))) {
  250.             mntmp = i;
  251.             len = m_i_len;
  252.         }
  253.         }
  254.     }
  255.     if (mntmp == -1) mntmp = title_to_mon(str, (int *)0, (int *)0);
  256.     return mntmp;
  257. }
  258.  
  259. #endif /* OVL1 */
  260. #ifdef OVLB
  261.  
  262. #ifdef POLYSELF
  263. boolean
  264. webmaker(ptr)   /* creature can spin a web */
  265.     register struct permonst *ptr;
  266. {
  267.     return (ptr->mlet == S_SPIDER && ptr != &mons[PM_SCORPION]);
  268. }
  269. #endif
  270.  
  271. #endif /* OVLB */
  272. #ifdef OVL2
  273.  
  274. /* returns 3 values (0=male, 1=female, 2=none) */
  275. int
  276. gender(mtmp)
  277.     register struct monst *mtmp;
  278. {
  279.     if (is_neuter(mtmp->data)) return 2;
  280.     return mtmp->female;
  281. }
  282.  
  283. #endif /* OVL2 */
  284. #ifdef OVLB
  285.  
  286. boolean
  287. levl_follower(mtmp)
  288. register struct monst *mtmp;
  289. {
  290.     return (mtmp->mtame || (mtmp->data->mflags2 & M2_STALK) || is_fshk(mtmp)
  291.         || (mtmp->iswiz && !mon_has_amulet(mtmp)));
  292. }
  293.  
  294. struct permonst *
  295. player_mon()
  296. {
  297.     switch (pl_character[0]) {
  298.         case 'A': return &mons[PM_ARCHEOLOGIST];
  299.         case 'B': return &mons[PM_BARBARIAN];
  300.         case 'C': if (flags.female) return &mons[PM_CAVEWOMAN];
  301.             else return &mons[PM_CAVEMAN];
  302.         case 'E': return &mons[PM_ELF];
  303.         case 'H': return &mons[PM_HEALER];
  304.         case 'K': return &mons[PM_KNIGHT];
  305.         case 'P': if (flags.female) return &mons[PM_PRIESTESS];
  306.             else return &mons[PM_PRIEST];
  307.         case 'R': return &mons[PM_ROGUE];
  308.         case 'S': return &mons[PM_SAMURAI];
  309. #ifdef TOURIST
  310.         case 'T': return &mons[PM_TOURIST];
  311. #endif
  312.         case 'V': return &mons[PM_VALKYRIE];
  313.         case 'W': return &mons[PM_WIZARD];
  314.         default: impossible("what are you?");
  315.             return &mons[PM_HUMAN];
  316.     }
  317. }
  318.  
  319. const int grownups[][2] = { {PM_LITTLE_DOG, PM_DOG}, {PM_DOG, PM_LARGE_DOG},
  320.     {PM_HELL_HOUND_PUP, PM_HELL_HOUND}, {PM_KITTEN, PM_HOUSECAT},
  321.     {PM_HOUSECAT, PM_LARGE_CAT}, {PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON},
  322.     {PM_KOBOLD, PM_LARGE_KOBOLD}, {PM_LARGE_KOBOLD, PM_KOBOLD_LORD},
  323.     {PM_GNOME, PM_GNOME_LORD}, {PM_GNOME_LORD, PM_GNOME_KING},
  324.     {PM_DWARF, PM_DWARF_LORD}, {PM_DWARF_LORD, PM_DWARF_KING},
  325.     {PM_SMALL_MIMIC, PM_LARGE_MIMIC}, {PM_LARGE_MIMIC, PM_GIANT_MIMIC},
  326.     {PM_BAT, PM_GIANT_BAT},
  327.     {PM_LICH, PM_DEMILICH}, {PM_DEMILICH, PM_MASTER_LICH},
  328.     {PM_OGRE, PM_OGRE_LORD}, {PM_OGRE_LORD, PM_OGRE_KING},
  329.     {PM_VAMPIRE, PM_VAMPIRE_LORD},
  330.     {PM_BABY_RED_DRAGON, PM_RED_DRAGON},
  331.     {PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON},
  332.     {PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON},
  333.     {PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON},
  334.     {PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON},
  335.     {PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON},
  336.     {PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON},
  337.     {PM_RED_NAGA_HATCHLING, PM_RED_NAGA},
  338.     {PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA},
  339.     {PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA},
  340.     {PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA},
  341.     {PM_BABY_PURPLE_WORM, PM_PURPLE_WORM},
  342.     {PM_BABY_LONG_WORM, PM_LONG_WORM},
  343. #ifdef ARMY
  344.     {PM_SOLDIER, PM_SERGEANT},
  345.     {PM_SERGEANT, PM_LIEUTENANT},
  346.     {PM_LIEUTENANT, PM_CAPTAIN},
  347. #endif
  348.     {PM_WATCHMAN, PM_WATCH_CAPTAIN},
  349.     {PM_BABY_CROCODILE, PM_CROCODILE},
  350.     {-1,-1}
  351. };
  352.  
  353. int
  354. little_to_big(montype)
  355. int montype;
  356. {
  357. #ifndef AIXPS2_BUG
  358.     register int i;
  359.     
  360.     for(i=0; grownups[i][0] >= 0; i++)
  361.         if(montype == grownups[i][0]) return grownups[i][1];
  362.     return montype;
  363. #else
  364. /* AIX PS/2 C-compiler 1.1.1 optimizer does not like the above for loop,
  365.  * and causes segmentation faults at runtime.  (The problem does not
  366.  * occur if -O is not used.)
  367.  * lehtonen@cs.Helsinki.FI (Tapio Lehtonen) 28031990
  368.  */
  369.     int i;
  370.     int monvalue;
  371.  
  372.     monvalue = montype;
  373.     for(i=0; grownups[i][0] >= 0; i++)
  374.         if(montype == grownups[i][0]) monvalue = grownups[i][1];
  375.     
  376.     return monvalue;
  377. #endif
  378. }
  379.  
  380. int
  381. big_to_little(montype)
  382. int montype;
  383. {
  384.     register int i;
  385.     
  386.     for(i=0; grownups[i][0] >= 0; i++)
  387.         if(montype == grownups[i][1]) return grownups[i][0];
  388.     return montype;
  389. }
  390.  
  391.  
  392. const char *
  393. locomotion(ptr, def)
  394. const struct permonst *ptr;
  395. const char *def;
  396. {
  397.     return (
  398.         is_floater(ptr) ? (const char *)"float" :
  399.         is_flyer(ptr)   ? (const char *)"fly" :
  400.         slithy(ptr)     ? (const char *)"slither" :
  401.         amorphous(ptr)  ? (const char *)"ooze" :
  402.         nolimbs(ptr)    ? (const char *)"crawl" :
  403.         def
  404.            );
  405.  
  406. }
  407.  
  408. #endif /* OVLB */
  409.  
  410. /*mondata.c*/
  411.